package org.lex.ftp.ui.calculator;

import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;

import javax.swing.*;

import org.lex.ftp.FTP;
import org.lex.ftp.model.FTPModel;
import org.lex.ftp.net.find.FTPFileIterator;
import org.lex.net.ftp.IFTPClient;
import org.lex.net.ftp.IFTPFile;
import org.lex.utils.text.SizeFormat;


public class CalculatePane extends JPanel {
	private JLabel serverLabel = null;
	private JTextField serverTextField = null;
	private JLabel pathLabel = null;
	private JTextField pathTextField = null;
	private JLabel foldersLabel = null;
	private JTextField foldersTextField = null;
	private JLabel filesLabel = null;
	private JTextField filesTextField = null;
	private JProgressBar progressBar = null;
	private JPanel gluePane = null;
	private JPanel buttonsPane = null;
	private JButton startButton = null;
	private JButton stopButton = null;
	private JButton closeButton = null;
	private JLabel sizeLabel = null;
	private JTextField sizeTextField = null;
	private SwingWorker calculator = null; // @jve:decl-index=0:
	private final FTP app;

	public CalculatePane(FTP app) {
		super();
		this.app = app;
		initialize();
		fill();
	}

	private void fill() {
		FTPModel model = app.getFTPExplorer().getFTPModel();
		this.getServerTextField().setText(model.getFTPURL().getServer());
		this.getPathTextField().setText(model.getCatalog());
	}

	private void start() {
		this.setRunning(true);
		calculator = new SwingWorker<Void, IFTPFile>() {
			private int folders = 0;
			private int files = 0;
			private long size = 0L;

			@Override
			protected Void doInBackground() throws Exception {
				FTPModel model = app.getFTPExplorer().getFTPModel();
				String pwd = model.getCatalog();
				IFTPClient ftp = model.getFTPClient();
				FTPFileIterator dfs = new FTPFileIterator(ftp, pwd);
				getProgressBar().setModel(dfs);
				while (dfs.hasNext())
					this.publish(dfs.next());
				app.getFTPExplorer().getFTPModel().setCatalog(pwd);
				return null;
			}

			@Override
			protected void process(List<IFTPFile> chunks) {
				for (IFTPFile file : chunks) {
					if (file.isFile()) {
						files++;
						size += file.getSize();
					} else
						folders++;
				}
				getSizeTextField().setText(SizeFormat.autoFormat(size));
				getFilesTextField().setText(Integer.toString(files));
				getFoldersTextField().setText(Integer.toString(folders));
			}

			@Override
			protected void done() {
				setRunning(false);
			}
		};
		calculator.execute();
	}

	private void stop() {
		this.setRunning(false);
		if (null != calculator) {
			calculator.cancel(true);
			calculator = null;
		}
	}

	private void setRunning(boolean b) {
		this.getStartButton().setEnabled(!b);
		this.getStopButton().setEnabled(b);
	}

	private JButton getStartButton() {
		if (startButton == null) {
			startButton = new JButton();
			startButton.setText("Start");
			startButton.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					start();
				}
			});
		}
		return startButton;
	}

	private JButton getStopButton() {
		if (stopButton == null) {
			stopButton = new JButton();
			stopButton.setText("Stop");
			stopButton.setEnabled(false);
			stopButton.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					stop();
				}
			});
		}
		return stopButton;
	}

	JButton getCloseButton() {
		if (closeButton == null) {
			closeButton = new JButton();
			closeButton.setText("Close");
			closeButton.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					stop();
				}
			});
		}
		return closeButton;
	}

	private void initialize() {
		GridBagConstraints gridBagConstraints12 = new GridBagConstraints();
		gridBagConstraints12.fill = GridBagConstraints.HORIZONTAL;
		gridBagConstraints12.gridy = 1;
		gridBagConstraints12.weightx = 1.0;
		gridBagConstraints12.insets = new Insets(0, 0, 5, 0);
		gridBagConstraints12.gridx = 3;
		GridBagConstraints gridBagConstraints11 = new GridBagConstraints();
		gridBagConstraints11.gridx = 2;
		gridBagConstraints11.anchor = GridBagConstraints.WEST;
		gridBagConstraints11.insets = new Insets(0, 0, 5, 5);
		gridBagConstraints11.gridy = 1;
		sizeLabel = new JLabel();
		sizeLabel.setText("Size:");
		GridBagConstraints gridBagConstraints10 = new GridBagConstraints();
		gridBagConstraints10.gridx = 0;
		gridBagConstraints10.gridwidth = 4;
		gridBagConstraints10.fill = GridBagConstraints.HORIZONTAL;
		gridBagConstraints10.weightx = 10.0;
		gridBagConstraints10.gridy = 5;
		GridBagConstraints gridBagConstraints9 = new GridBagConstraints();
		gridBagConstraints9.gridx = 0;
		gridBagConstraints9.fill = GridBagConstraints.BOTH;
		gridBagConstraints9.gridwidth = 4;
		gridBagConstraints9.weightx = 10.0;
		gridBagConstraints9.weighty = 10.0;
		gridBagConstraints9.gridy = 4;
		GridBagConstraints gridBagConstraints8 = new GridBagConstraints();
		gridBagConstraints8.gridx = 0;
		gridBagConstraints8.gridwidth = 4;
		gridBagConstraints8.fill = GridBagConstraints.HORIZONTAL;
		gridBagConstraints8.weightx = 1.0;
		gridBagConstraints8.insets = new Insets(0, 0, 12, 0);
		gridBagConstraints8.gridy = 3;
		GridBagConstraints gridBagConstraints7 = new GridBagConstraints();
		gridBagConstraints7.fill = GridBagConstraints.HORIZONTAL;
		gridBagConstraints7.gridy = 2;
		gridBagConstraints7.weightx = 1.0;
		gridBagConstraints7.insets = new Insets(0, 0, 5, 0);
		gridBagConstraints7.gridx = 3;
		GridBagConstraints gridBagConstraints6 = new GridBagConstraints();
		gridBagConstraints6.gridx = 2;
		gridBagConstraints6.anchor = GridBagConstraints.WEST;
		gridBagConstraints6.insets = new Insets(0, 0, 5, 5);
		gridBagConstraints6.gridy = 2;
		filesLabel = new JLabel();
		filesLabel.setText("Files:");
		GridBagConstraints gridBagConstraints5 = new GridBagConstraints();
		gridBagConstraints5.fill = GridBagConstraints.HORIZONTAL;
		gridBagConstraints5.gridy = 2;
		gridBagConstraints5.weightx = 1.0;
		gridBagConstraints5.insets = new Insets(0, 0, 5, 5);
		gridBagConstraints5.gridx = 1;
		GridBagConstraints gridBagConstraints4 = new GridBagConstraints();
		gridBagConstraints4.gridx = 0;
		gridBagConstraints4.anchor = GridBagConstraints.WEST;
		gridBagConstraints4.insets = new Insets(0, 0, 5, 5);
		gridBagConstraints4.gridy = 2;
		foldersLabel = new JLabel();
		foldersLabel.setText("Folders:");
		GridBagConstraints gridBagConstraints3 = new GridBagConstraints();
		gridBagConstraints3.fill = GridBagConstraints.HORIZONTAL;
		gridBagConstraints3.gridy = 1;
		gridBagConstraints3.weightx = 1.0;
		gridBagConstraints3.insets = new Insets(0, 0, 5, 5);
		gridBagConstraints3.gridx = 1;
		GridBagConstraints gridBagConstraints2 = new GridBagConstraints();
		gridBagConstraints2.gridx = 0;
		gridBagConstraints2.anchor = GridBagConstraints.WEST;
		gridBagConstraints2.insets = new Insets(0, 0, 5, 5);
		gridBagConstraints2.gridy = 1;
		pathLabel = new JLabel();
		pathLabel.setText("Path:");
		GridBagConstraints gridBagConstraints1 = new GridBagConstraints();
		gridBagConstraints1.fill = GridBagConstraints.HORIZONTAL;
		gridBagConstraints1.gridy = 0;
		gridBagConstraints1.weightx = 1.0;
		gridBagConstraints1.insets = new Insets(0, 0, 5, 0);
		gridBagConstraints1.gridwidth = 3;
		gridBagConstraints1.gridx = 1;
		GridBagConstraints gridBagConstraints = new GridBagConstraints();
		gridBagConstraints.gridx = 0;
		gridBagConstraints.anchor = GridBagConstraints.WEST;
		gridBagConstraints.insets = new Insets(0, 0, 5, 5);
		gridBagConstraints.gridy = 0;
		serverLabel = new JLabel();
		serverLabel.setText("Server:");
		this.setSize(300, 200);
		this.setLayout(new GridBagLayout());
		this.add(serverLabel, gridBagConstraints);
		this.add(getServerTextField(), gridBagConstraints1);
		this.add(pathLabel, gridBagConstraints2);
		this.add(getPathTextField(), gridBagConstraints3);
		this.add(foldersLabel, gridBagConstraints4);
		this.add(getFoldersTextField(), gridBagConstraints5);
		this.add(filesLabel, gridBagConstraints6);
		this.add(getFilesTextField(), gridBagConstraints7);
		this.add(getProgressBar(), gridBagConstraints8);
		this.add(getGluePane(), gridBagConstraints9);
		this.add(getButtonsPane(), gridBagConstraints10);
		this.add(sizeLabel, gridBagConstraints11);
		this.add(getSizeTextField(), gridBagConstraints12);
	}

	private JTextField getServerTextField() {
		if (serverTextField == null) {
			serverTextField = new JTextField();
			serverTextField.setEditable(false);
		}
		return serverTextField;
	}

	private JTextField getPathTextField() {
		if (pathTextField == null) {
			pathTextField = new JTextField();
			pathTextField.setEditable(false);
		}
		return pathTextField;
	}

	private JTextField getFoldersTextField() {
		if (foldersTextField == null) {
			foldersTextField = new JTextField();
			foldersTextField.setEditable(false);
		}
		return foldersTextField;
	}

	private JTextField getFilesTextField() {
		if (filesTextField == null) {
			filesTextField = new JTextField();
			filesTextField.setEditable(false);
		}
		return filesTextField;
	}

	private JProgressBar getProgressBar() {
		if (progressBar == null) {
			progressBar = new JProgressBar();
			progressBar.setStringPainted(true);
		}
		return progressBar;
	}

	private JPanel getGluePane() {
		if (gluePane == null) {
			gluePane = new JPanel();
			gluePane.setLayout(new GridBagLayout());
		}
		return gluePane;
	}

	private JPanel getButtonsPane() {
		if (buttonsPane == null) {
			FlowLayout flowLayout = new FlowLayout();
			flowLayout.setHgap(11);
			flowLayout.setVgap(0);
			buttonsPane = new JPanel();
			buttonsPane.setLayout(flowLayout);
			buttonsPane.add(getStartButton(), null);
			buttonsPane.add(getStopButton(), null);
			buttonsPane.add(getCloseButton(), null);
		}
		return buttonsPane;
	}

	private JTextField getSizeTextField() {
		if (sizeTextField == null) {
			sizeTextField = new JTextField();
			sizeTextField.setEditable(false);
		}
		return sizeTextField;
	}
}
